﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Runtime.Serialization;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Collections.Generic;
using System.Threading;
using System.Text;
using System.ServiceModel;

namespace Testy
{
    public class BLClient
    {
        private const string DataServiceAddress = "/DataService.svc";
        private static Uri DataServiceUri = GetAbsoluteUri(DataServiceAddress);
        private static ChannelFactory<IDataService> DataServiceFactory =
            new ChannelFactory<IDataService>(new BasicHttpBinding(),
                new EndpointAddress(DataServiceUri));
        private static IDataService DataServiceChannel = DataServiceFactory.CreateChannel();

        public static void DataServiceDebug(Uri serviceUri)
        {
            ChannelFactory<IDataService> scf;
            scf = new ChannelFactory<IDataService>(new BasicHttpBinding(), 
                new EndpointAddress(serviceUri));
            IDataService serv = scf.CreateChannel();
            try
            {
                
                serv.BeginGetProjects((IAsyncResult ar) =>
                    {
                        //Project prj =
                        object obj =
                            ((IDataService)ar.AsyncState).EndGetProjects(ar);
                        //bool head = prj.IsHead;
                        object obj2 = obj;
                    }, serv);
                
                /*
                serv.BeginSayHello("Dimas", (IAsyncResult ar) =>
                    {
                        try
                        {
                            string answer =
                                ((IDataService)ar.AsyncState).EndSayHello(ar);
                        }
                        catch (Exception ex)
                        {
                            string msg = ex.Message;
                        }
                        //string s1 = answer;
                    }, serv);
                */
            }
            catch (Exception ex)
            {
                string mess = ex.Message;
            }
        }

        public static void Service_GetProjects(SynchronizationContext UIcontext, 
            SendOrPostCallback callback)
        {
            DataServiceChannel.BeginGetProjects((IAsyncResult ar) =>
            {
                Project prj =                
                    ((IDataService)ar.AsyncState).EndGetProjects(ar);
                UIcontext.Send(callback, prj);
            }, DataServiceChannel);
        }

        public static void Service_AddDeleteRenameProject(string loginToken, string projectID, 
            bool isAddSubproject, string newProjectName,
            SynchronizationContext UIcontext, SendOrPostCallback callback)
        {
            DataServiceChannel.BeginAddDeleteRenameProject(loginToken, projectID, isAddSubproject, newProjectName,
                (IAsyncResult ar) => 
                {
                    bool res = ((IDataService)ar.AsyncState).EndAddDeleteRenameProject(ar);
                    UIcontext.Send(callback, res);
                }, DataServiceChannel);
        }

        public static void Service_Login(string name, string password,
            SynchronizationContext UIcontext,
            SendOrPostCallback callback)
        {
            DataServiceChannel.BeginLogin(name, password, (IAsyncResult ar) =>
            {
                string token =
                    ((IDataService)ar.AsyncState).EndLogin(ar);
                UIcontext.Send(callback, token);
            }, DataServiceChannel);
        }

        public static void Service_GetIssues(string token,
            SynchronizationContext UIcontext,
            SendOrPostCallback callback)
        {
            DataServiceChannel.BeginGetIssues(token, (IAsyncResult ar) =>
            {
                List<ProjectIssue> issues =
                    ((IDataService)ar.AsyncState).EndGetIssues(ar);
                UIcontext.Send(callback, issues);
            }, DataServiceChannel);
        }        

        public static void Service_PostIssueDetail(string loginToken, string issueID, string detailInfo,
            SynchronizationContext UIcontext, SendOrPostCallback callback)
        {
            DataServiceChannel.BeginPostIssueDetail(loginToken, issueID, detailInfo, (IAsyncResult ar) => 
            {
                bool res = ((IDataService)ar.AsyncState).EndPostIssueDetail(ar);
                UIcontext.Send(callback, res);
            }, DataServiceChannel);            
        }

        public static void Service_PostIssue(string loginToken, string projectID, string issueName,
            ProjectIssueType issueType, string firstDetailInfo, SynchronizationContext UIcontext, SendOrPostCallback callback)
        {
            DataServiceChannel.BeginPostIssue(loginToken, projectID, issueName, issueType, firstDetailInfo,
                (IAsyncResult ar) =>
                {
                    bool res = ((IDataService)ar.AsyncState).EndPostIssue(ar);
                    UIcontext.Send(callback, res);
                }, DataServiceChannel);
        }

        public static void Service_UpdateIssueName(string loginToken, string issueID, string newIssueName,
            SynchronizationContext UIcontext, SendOrPostCallback callback)
        {
            DataServiceChannel.BeginUpdateIssueName(loginToken, issueID, newIssueName, (IAsyncResult ar) =>
            {
                bool res = ((IDataService)ar.AsyncState).EndUpdateIssueName(ar);
                UIcontext.Send(callback, res);
            }, DataServiceChannel);
        }

        public static void Service_GetUsers(SynchronizationContext UIcontext,
            SendOrPostCallback callback)
        {
            DataServiceChannel.BeginGetUsers((IAsyncResult ar) =>
            {
                List<User> users =
                    ((IDataService)ar.AsyncState).EndGetUsers(ar);
                UIcontext.Send(callback, users);
            }, DataServiceChannel);
        }

        public static void Service_AddUser(string login, string password,
            SynchronizationContext UIcontext, SendOrPostCallback callback)
        {
            DataServiceChannel.BeginAddUser(login, password, 
                (IAsyncResult ar) => 
                {
                    bool res = ((IDataService)ar.AsyncState).EndAddUser(ar);
                    UIcontext.Send(callback, res);
                }, DataServiceChannel);
        }

        public static void Service_UpdateUserNamePassword(string loginToken, string oldPassword,
            string newPassword, string newName,
            SynchronizationContext UIcontext, SendOrPostCallback callback)
        {
            DataServiceChannel.BeginUpdateUserNamePassword(loginToken, oldPassword, newPassword, newName,
                (IAsyncResult ar) =>
                {
                    bool res = ((IDataService)ar.AsyncState).EndUpdateUserNamePassword(ar);
                    UIcontext.Send(callback, res);
                }, DataServiceChannel);
        }

        public static Uri GetAbsoluteUri(string relativePath)
        {
            string fullpath = App.Current.Host.Source.OriginalString;
            string slpath = App.Current.Host.Source.LocalPath;
            string hostpath = fullpath.Remove(fullpath.IndexOf(slpath));
            return new Uri(hostpath + relativePath, UriKind.Absolute);
        }

        /*
        public static void CreateRequest(Uri addr, CommandList command, List<object> postData, Action<object> callback)
        {
            CreateRequest(addr, new PostDataSet(command, postData), callback);
        }

        public static void CreateRequest(Uri addr, PostDataSet postData, Action<object> callback)
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(addr);
            //Get request
            if (postData == null)
            {                
                request.BeginGetResponse((IAsyncResult ar) => 
                {
                    RequestData rd = (RequestData)ar.AsyncState;                    
                    HttpWebResponse resp = (HttpWebResponse)rd.Request.EndGetResponse(ar);                    
                    string recievedData = new StreamReader(resp.GetResponseStream()).ReadToEnd();
                    rd.Callback(recievedData);
                }, 
                    new RequestData(request, callback, null));
            }
            //Post request
            else
            {
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                request.BeginGetRequestStream((IAsyncResult ar1)=>
                {
                    RequestData rd1 = (RequestData)ar1.AsyncState;
                    Stream s = rd1.Request.EndGetRequestStream(ar1);
                    DCJS_PostDataSet.WriteObject(s, rd1.PostData);
                    //sw.Write();
                    s.Flush();
                    s.Close();                    

                    request.BeginGetResponse((IAsyncResult ar2) =>
                    {
                        RequestData rd2 = (RequestData)ar2.AsyncState;                        
                        HttpWebResponse resp2 = (HttpWebResponse)rd2.Request.EndGetResponse(ar2);
                        string recievedData = 
                            new StreamReader(resp2.GetResponseStream()).ReadToEnd();
                        rd2.Callback(recievedData);
                    }, rd1);
                },
                    new RequestData(request, callback, postData));
            }
        }

        public static DataContractJsonSerializer DCJS_PostDataSet =
                        new DataContractJsonSerializer(typeof(PostDataSet));

        public static DataContractJsonSerializer DCJS_ProjectIssue_List =
                        new DataContractJsonSerializer(typeof(List<ProjectIssue>));
        */
    }
}
